#include <QApplication>
#include <QVector>
#include <QDir>
#include <QDebug>
#include <QMainWindow>
#include <QMdiArea>

#include "appsettings.h"
#include "microscheme.h"
#include "node.h"
#include "inelement.h"
#include "realelement.h"
#include "fluffy.h"
#include "objectsloader.h"
#include "instantiator.h"

#include "../drawings/signaldiagram.h"
#include "../drawings/schemewindow.h"

#include "linetest.h"
#include "rs_test.h"

#include "fluffy.h"
#include "rectangle.h"
#include "circle.h"
#include "path.h"
#include "textline.h"

//Вывести странную строку на основе сигнала
QString getSignals(SignalContainer* container)
{
    QString res = "";
    if (container != NULL)
    {
        for (int i = 0; i < container->getItems().count();i++)
        {
            Interval ix = container->getItems().at(i);
            QString chr = "T";
            if (ix.signal == 0)
                chr = "_";
            else
                if (ix.signal == -1)
                    chr = "-";
            for (int j = 0; j < ix.time; j++)
                res += chr;
        }
    }
    return res;
}

/*
 * Тесты работы объектов приложения
 * Конструкторы/Деструкторы и прочее
 */
void work_test()
{
    MicroScheme scheme;

    InElement* in = new InElement();
    in->init("input.xml");
    scheme.appendObject(in);

    //delete in;

    RealElement* nand2 = new RealElement();
    nand2->init("nand2.xml");
    scheme.appendObject(nand2);

    ElementImage* img = nand2->getImage();
    img->create(100,100);
    img->paintToBuffer(1.0);
    img->getBufferImage()->save("oh.png");
    delete img;

    qDebug() << "AllRight" << endl;

    //delete nand2;

    //scheme->Elements.append(node);
    //qDebug() << in->GetInfo().toAscii() << endl;
    //qDebug() << nand2->GetInfo().toAscii() << endl;
    //delete scheme;
}

//Тест простого элемента NAND2
void nand_test()
{
    qDebug() << "NAND2 TEST " << endl;
    LineTest test;
    QVector<SignalContainer*> results = test.testIt();

    SignalDiagram *sg = new SignalDiagram();
    sg->timeTableVisible = true;
    sg->timeTagsVisible = true;
    sg->drawFont.setPixelSize(12);
    sg->drawFont.setBold(true);
    sg->generateDiagram(results, 400, 400, 0, 0, 1.5f);

    QImage* img = sg->generateImage(1.5f);

    img->save("nand4.png","png",100);

    delete img;
    delete sg;

    for (int i = 0; i < results.count(); i++)
    {
        SignalContainer* x = results.at(i);
        qDebug() << x->sortIndex;
        qDebug() << x->label << " : " << getSignals(x) << endl;
    }
    qDeleteAll(results);

    qDebug() << "END TEST " << endl;
}

//Тест RS Асинхронного Триггера
void rs_test()
{
    qDebug() << "RS TEST " << endl;
    RS_Test test;
    QVector<SignalContainer*> results = test.testIt();

    for (int i = 0; i < results.count(); i++)
    {
        SignalContainer* x = results.at(i);
        qDebug() << x->label << " : " << getSignals(x) << endl;
    }

    qDeleteAll(results);

    qDebug() << "END TEST " << endl;
}

//Тест сохранения и отрисовки графики
void fluffy_test(){
    FluffyImage* image = new FluffyImage("fluffy-load.svg");
    image->saveToXml("fluffy-save.svg");

    // CIRCLE
    Circle* circle = new Circle();
    circle->radius = 65;
    circle->strokeWidth = 5;
    circle->centerPoint.setX(200);
    circle->centerPoint.setY(200);
    circle->fillColor.setNamedColor("red");
    circle->strokeColor.setNamedColor("blue");
    image->objects.append(circle);

    //RECT
    Rectangle* rect = new Rectangle();
    rect->width = 50;
    rect->height = 75;
    rect->topLeftPoint.setX(100);
    rect->topLeftPoint.setY(100);
    rect->fillColor.setNamedColor("yellow");
    rect->strokeColor.setNamedColor("brown");
    rect->strokeWidth = 7;
    image->objects.append(rect);

    //PATH
    Path* path = new Path();

    Path::Segment p;
    p.point.setX(15);
    p.point.setY(20);
    p.type = Path::Point_MoveTo;

    Path::Segment m;
    m.point.setX(40);
    m.point.setY(40);
    m.type = Path::Point_LineTo;

    Path::Segment s;
    s.point.setX(75);
    s.point.setY(190);
    s.type = Path::Point_LineTo;

    path->segments.append(p);
    path->segments.append(m);
    path->segments.append(s);

    path->strokeColor.setNamedColor("cyan");
    path->strokeWidth = 4;
    path->fillColor.setNamedColor("navy");
    image->objects.append(path);

    //TEXT
    TextLine* text = new TextLine();
    text->topLeftPoint.setX(250);
    text->topLeftPoint.setY(250);
    text->text = "OLOLO!";
    text->fillColor.setNamedColor("red");
    text->strokeColor.setAlphaF(1.0);;
    text->strokeWidth = 3;
    text->textFont.setFamily("Sans");
    text->textFont.setPixelSize(40);
    image->objects.append(text);

    image->setHeight(500);
    image->setWidth(500);
    image->saveToXml("fluffy-test.svg");
    QImage qimage(500, 500, QImage::Format_ARGB32_Premultiplied);

    image->draw(&qimage,1.0);
    qimage.save("image.png");

    delete image;
}

//Тест фабрики элементов
void instant_test()
{
    Instantiator& constructor = Instantiator::getInstance();

    RealElement* re = (RealElement*)constructor.buildElement("nand2");
    re->getImage()->getBufferImage()->save("nand2.png");

    delete re;
}

/*
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    // Инициализация ресурсов в библиотеках
    Q_INIT_RESOURCE(DrawingsRes);

    // На время тестов используем дирректорию ../Objects
    AppSettings::ConfigPath = QDir::convertSeparators(QDir::currentPath())
                              + QDir::separator()
                              + "Config";
    
    AppSettings& appSettings = AppSettings::getInstance();
    ObjectsLoader& objectsLoader = ObjectsLoader::getInstance();

    //директория конфигураций
    appSettings.configPath = QDir("../objects").absolutePath();
    //Задать шрифт
    appSettings.defaultFontFamily = "Arial";

    objectsLoader.scanConfigs();

    //сделать тесты приложения
    //work_test();

    instant_test();

    //сделать тесты логики
    //nand_test();

    //сделать тест триггера
    //rs_test();

    //тест fluffy
    //fluffy_test();

//    QMainWindow m;
//    m.setGeometry(100,100,200,200);
//    QMdiArea* area = new QMdiArea(&m);
//    area->setDocumentMode(true);
//    area->setTabShape(QTabWidget::Rounded);
//    m.setCentralWidget(area);
//    m.show();

//    SchemeWindow* w = new SchemeWindow(NULL);
//    w->setGeometry(100,100,100,100);
//    area->addSubWindow(w);
//    w->showMaximized();

    return 0;// a.exec();
}
*/
